package redis.manage.impl;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import redis.manage.RedisManager;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 *
 * ClassName:RedisServiceIm <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * Date:     2019年9月3日 上午11:41:42 <br/>
 * @author   Owner
 * @version
 * @since    JDK 1.8
 * @see
 */
public class RedisManagerImpl implements RedisManager {

    private   Long  expireExtendTime = 0L;

    public RedisManagerImpl(Long t) {
        this.expireExtendTime =  (long) Math.random()*t;
    }

    public RedisManagerImpl() {
    }


    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    public boolean set(String key, Object value) {
        try {
            ValueOperations<Object , Object> operations =redisTemplate.opsForValue();
            operations.set(key, value);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    public boolean set(String key, Object value, Long expireTime) {

        try {
            ValueOperations<Object , Object> operations =redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime+expireExtendTime, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    public void remove(String... keys) {
        for(String key:keys) {
            remove(key);
        }

    }


    public void removePattern(String pattern) {
        Set<Object> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0) {
            redisTemplate.delete(keys);
        }
    }


    public void remove(String key) {
        if(exists(key)) {
            redisTemplate.delete(key);
        }
    }


    public boolean exists(String key) {
        return redisTemplate.hasKey( key);
    }


    @SuppressWarnings("unchecked")
    public <T> T get(String key) {

        ValueOperations<Object, T> operations = (ValueOperations<Object, T>) redisTemplate.opsForValue();
        return operations.get(key);
    }


    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations<Object, Object, Object> hash = redisTemplate.opsForHash();
        hash.put( key, hashKey, value);
    }



    public void hmSet(String key, Object hashKey, Object value, Long expireTime) {

        HashOperations<Object, Object, Object> hash = redisTemplate.opsForHash();
        hash.put( key, hashKey, value);
        redisTemplate.expire(hashKey, expireTime+expireExtendTime, TimeUnit.SECONDS);

    }


    public Object hmGet(String key, Object hashKey) {
        HashOperations<Object, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get( key, hashKey);
    }


    public void lPush(String k, Object v) {
        ListOperations<Object, Object> list = redisTemplate.opsForList();
        list.rightPush(k, v);
    }


    public List<Object> lRange(String key, long start, long stop) {
        ListOperations<Object, Object> list = redisTemplate.opsForList();
        return list.range(key, start, stop);
    }


    public void add(String key, Object value) {
        SetOperations<Object, Object> set = redisTemplate.opsForSet();
        set.add( key, value);
    }


    public Set<Object> setMembers(String key) {
        SetOperations<Object, Object> set = redisTemplate.opsForSet();
        return set.members( key);
    }


    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations<Object, Object> zset = redisTemplate.opsForZSet();
        zset.add(key, value, scoure);
    }


    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations<Object, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore( key, scoure, scoure1);
    }


    public Map<Object, Object> hmMap(String key) {
        HashOperations<Object, Object, Object> operations = redisTemplate.opsForHash();
        Map<Object, Object> mapInRedis = operations.entries(key);
        return mapInRedis;
    }


    public Long incr(String key, long liveTime,Integer  defaultValue) {
        Long ins=  redisTemplate.opsForValue().increment(key, defaultValue == null ? 1L:defaultValue);
        redisTemplate.expire(key, liveTime, TimeUnit.SECONDS);
        return ins;
    }



    public Long getExpireTime(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);

    }


    @SuppressWarnings("unchecked")
    public <T> List<T> parmGet(String key) {
        List<T>  res=new ArrayList<T>();

        Set<Object> keys = redisTemplate.keys(key + "*");
        for(Object s:keys){
            res.add((T) get((String)s));
        }
        return res;
    }


    @SuppressWarnings("unchecked")
    public <T> Map<Long, T> getLiveTimeAndValue(String key) {

        Map<Long, T>  res=new HashMap<Long, T>();
        res.put(redisTemplate.getExpire(key), (T) get(key));
        return res;
    }


    public void delyLiveTime(String key, Long secs) {

        redisTemplate.expire(key, secs, TimeUnit.SECONDS);

    }














}

